package com.gy.spring.mvc.common.tools;

import java.lang.reflect.Field;

import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableName;

/**
 * TODO 基于MyBatis的SQL语句生成工具
 *
 * @author geYang
 * @date 2018-04-11
 */
public class EntityTool {

    /**
     * TODO 获取对象属性,用于SQL查询
     *
     * @param t
     * @return "name,age,..."
     * @throws Exception
     * @author geYang
     * @date 2018-04-11 13:56
     */
    public <T> String getFields(Class<T> t) throws Exception {
        return getFields(t, 1, null, null);
    }

    /**
     * TODO 获取查询语句
     *
     * @param t 查询对象
     * @return SELECT id,nickname... FROM user
     * @throws Exception
     * @author geYang
     * @date 2018-04-12 10:34
     */
    public <T> String getSelect(Class<T> t) throws Exception {
        return "SELECT " + getFields(t) + " FROM " + getTableName(t);
    }

    /**
     * TODO MyBatis插入语句
     *
     * @param t
     * @return
     * @author geYang
     * @date 2018-04-12 17:17
     */
    public <T> String getInsert(Class<T> t) {
        StringBuffer str = new StringBuffer("INSERT INTO " + getTableName(t) + " ( ");
        // 数据表字段
        str.append(getFields(t, 2, null, null));
        str.append(" ) VALUES ( ");
        // 对象字段
        str.append(getFields(t, 3, "#{", "}"));
        str.append(" )");
        return str.toString();
    }

    /**
     * TODO MyBatis插入语句(if条件)
     *
     * @param t
     * @return
     * @author geYang
     * @date 2018-04-12 16:39
     */
    public <T> String getIfInsert(Class<T> t) {
        StringBuffer str = new StringBuffer("INSERT INTO " + getTableName(t));
        str.append(getIfFields(t, true));
        str.append("VALUES");
        str.append(getIfFields(t, false));
        return str.toString();
    }

    /**
     * TODO MyBatis更新语法(if,id)
     *
     * @param t
     * @return
     * @author geYang
     * @date 2018-04-12 17:19
     */
    public <T> String getUpdate(Class<T> t) {
        StringBuffer str = new StringBuffer("UPDATE " + getTableName(t));
        Field[] fields = t.getDeclaredFields();
        str.append("\n<trim prefix=\"SET\" suffixOverrides=\",\">");
        for (Field field : fields) {
            //对象名称
            String name = field.getName();
            //字段名称
            String dbName = name;
            if (!"serialVersionUID".equals(name)) {
                if (field.isAnnotationPresent(TableField.class)) {
                    dbName = field.getDeclaredAnnotation(TableField.class).value();
                }
                str.append("\n<if test=\"" + name + " != null\">\n");
                str.append(dbName + "=#{" + name + "},");
                str.append("\n</if>");
            }
        }
        str.append("\n</trim>\n WHERE id=#{id}");
        return str.toString();
    }

    /**
     * TODO MySQL删除语句
     *
     * @param t
     * @return
     * @author geYang
     * @date 2018-04-13 09:08
     */
    public <T> String getDelete(Class<T> t) {
        return "DELETE FROM " + getTableName(t) + " WHERE id=#{id}";
    }


    /**
     * TODO 获取对象数据库名称,驼峰转下划线
     *
     * @return User => user; UserLoging => user_login
     * @author geYang
     * @date 2018-04-12 13:24
     */
    private <T> String getTableName(Class<T> t) {
        String tableName = null;
        if (t.isAnnotationPresent(TableName.class)) {
            tableName = t.getDeclaredAnnotation(TableName.class).value();
        } else {
            //获取对象名
            String tName = t.getSimpleName();
            //声明对象表名
            StringBuffer tbName = new StringBuffer("");
            for (int i = 0; i < tName.length(); i++) {
                char c = tName.charAt(i);
                if (i == 0) {
                    //对象第一字母转小写
                    tbName.append(Character.toLowerCase(c));
                } else {
                    //判断其他字符为大写,加 _
                    if (Character.isUpperCase(c)) {
                        tbName.append("_" + Character.toLowerCase(c));
                    } else {
                        tbName.append(c);
                    }
                }
            }
            tableName = tbName.toString();
        }
        return tableName;
    }

    /**
     * TODO 获取对象数据库字段
     *
     * @param t
     * @param i      1: x_x AS xX ; 2: x_x ; 3: p xX s
     * @param prefix i==3 xX 的前缀
     * @param suffix i==3 xX 的后缀
     * @return 数据库字段
     * @author geYang
     * @date 2018-04-12 15:34
     */
    private <T> String getFields(Class<T> t, int i, String prefix, String suffix) {
        StringBuffer str = new StringBuffer("");
        Field[] fields = t.getDeclaredFields();
        for (Field field : fields) {
            String name = field.getName();
            if (!"serialVersionUID".equals(name)) {
                str.append(",");
                if (field.isAnnotationPresent(TableField.class)) {
                    String dbName = field.getDeclaredAnnotation(TableField.class).value();
                    if (i == 1) {
                        str.append(dbName + " AS " + name);
                    } else if (i == 2) {
                        str.append(dbName);
                    } else if (i == 3) {
                        if (prefix != null) {
                            str.append(prefix);
                        }
                        str.append(name);
                        if (suffix != null) {
                            str.append(suffix);
                        }
                    }
                } else {
                    if (i == 3) {
                        if (prefix != null) {
                            str.append(prefix);
                        }
                        str.append(name);
                        if (suffix != null) {
                            str.append(suffix);
                        }
                    } else {
                        str.append(name);
                    }
                }
            }
        }
        return str.toString().substring(1);
    }


    private <T> String getIfFields(Class<T> t, boolean b) {
        StringBuffer str = new StringBuffer("");
        Field[] fields = t.getDeclaredFields();
        str.append("\n<trim prefix=\"(\" suffixOverrides=\",\" suffix=\")\">");
        for (Field field : fields) {
            //对象名称
            String name = field.getName();
            //字段名称
            String dbName = name;
            if (!"serialVersionUID".equals(name)) {
                if (field.isAnnotationPresent(TableField.class)) {
                    dbName = field.getDeclaredAnnotation(TableField.class).value();
                }
                if (b) {
                    str.append("\n<if test=\"" + name + " != null\">\n");
                    str.append(dbName + ",");
                    str.append("\n</if>");
                } else {
                    str.append("\n<if test=\"" + name + " != null\">\n");
                    str.append("#{" + name + "},");
                    str.append("\n</if>");
                }
            }
        }
        str.append("\n</trim>\n");
        return str.toString();
    }


    /**
     * TODO 获取对象toString语句
     *
     * @param t
     * @return
     * @author geYang
     * @date 2018-04-12 11:25
     */
    public <T> String getToString(Class<T> t) {
        StringBuffer str = new StringBuffer("\"" + t.getSimpleName() + "{\"+");
        Field[] fields = t.getDeclaredFields();
        StringBuffer strfield = new StringBuffer();
        for (Field field : fields) {
            String name = field.getName();
            if (!"serialVersionUID".equals(name)) {
                strfield.append("\", " + name + "=\"+" + name + "+");
            }
        }
        str.append("\"" + strfield.substring(3, strfield.length()) + "\"}\"");
        return str.toString();
    }


}
